Cross-site Request Forgery
→CSRF
Cross-site Request Forgery
これで完璧!今さら振り返る CSRF 対策と同一オリジンポリシーの基礎
CSRF(Cross-Site Request Forgery)攻撃について
跨站請求偽造
利用網頁應用處理程序上的漏洞,進行原定以外處理的攻擊手法
例如使用短網指包覆指定行為的網址
導致使用者身份被盜用,從而進行非原定的行為
例如留下犯罪宣言的訊息
可以在request裡加入token驗證這個行為是否真的來自該使用者
https://www.youtube.com/watch?v=vRBihr41JTo
Computerphile
mixi
2005-04-23 大量の「はまちちゃん」を生み出したCSRFの脆弱性とは? - ITmedia エンタープライズ
範例
code:input.php
<form action="post.php" method="post">
<label>Title</label>
<input type="text" name="title">
<label>Content</label>
<textarea name="content"></textarea>
<button type="submit">Submit</button>
</form>
code:post.php
$title = $_POST'title' ?? null;
$content = $_POST'content' ?? null;
// 檢查輸入
if (!$title || !$content) {
throw new Exception('invalid input');
}
// 儲存至資料庫
$pdo->prepare('insert into posts(title, content) values (:title, :content)');
$pdo->execute([
':title' => $title,
':content' => $content,
]);
攻擊
輸入帶有另一個含攻擊程式碼網站 index.html 的 iframe
<iframe src="forgery.html" width="1" height"1">
code:forgery.html
<body onload="document.forgery.submit()">
<form name="forgery" action="http://sample.com/post.php" method="post">
<input type="hidden" name="title" value="Dangerous Title">
<input type="hidden" name="content" value="Dangerous Content">
</form>
</body>
受害者點進此含有攻擊程式碼的網站
會不知不覺以自己的 IP 地址和 UserAgent 傳送出有危險性的內容
e.g. 犯罪宣言
對策
加入 token 驗證
code:input.php
<?php
session_start();
$token = bin2hex(openssl_random_pseudo_bytes(16));
$_SESSION'token' = $token;
?>
<form action="post.php" method="post">
<input type="hidden" name="token" value="<?php echo $token; ?>">
<label>Title</label>
<input type="text" name="title">
<label>Content</label>
<textarea name="content"></textarea>
<button type="submit">Submit</button>
</form>
code:post.php
<?php
session_start();
if (
empty($_POST'token')
|| empty($_SESSION'token')
|| $_POST'token' !== $_SESSION'token'
) {
throw new Exception('token mismatched')
}
?>
// ...
CSRF 対策はいまだに Token が必須なのか?
CSRF対策のやり方、そろそろアップデートしませんか / Update your knowledge of CSRF protection - Speaker Deck
1. Token